package com.hospital.register.user.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hospital.register.common.constants.redis.UserRedisConstants;
import com.hospital.register.common.exception.BusinessException;
import com.hospital.register.common.helper.JwtHelper;
import com.hospital.register.common.result.ResultCodeEnum;
import com.hospital.register.constants.BaseEntityConstants;
import com.hospital.register.constants.UserInfoConstants;
import com.hospital.register.dto.user.UserAuthDto;
import com.hospital.register.dto.user.UserQueryDto;
import com.hospital.register.dto.user.VerificationCodeDto;
import com.hospital.register.enums.AuthStatusEnum;
import com.hospital.register.model.user.UserInfo;
import com.hospital.register.user.mapper.UserInfoMapper;
import com.hospital.register.user.service.UserInfoService;
import com.hospital.register.vo.user.LoginCodeVo;
import com.hospital.register.vo.user.UserQueryVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Date;

@Service
public class UserInfoServiceImpl implements UserInfoService {

    /**
     * 访问用户数据
     */
    @Autowired
    private UserInfoMapper userInfoMapper;

    /**
     * 访问 Redis
     */
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Override
    public LoginCodeVo loginWithVerificationCode(VerificationCodeDto param) {
        this.checkLoginVerificationCode(param);

        UserInfo userInfo = this.userInfoMapper.selectByPhone(param.getPhone());
        if (userInfo == null) {
            userInfo = this.insertPhoneUser(param.getPhone());
        }

        if (userInfo.getStatus() == UserInfoConstants.STATUS_LOCKED) {// 已锁定
            throw new BusinessException(ResultCodeEnum.LOGIN_DISABLED_ERROR);
        }

        // 封装返回数据
        LoginCodeVo result = new LoginCodeVo();
        result.setName(userInfo.getName());
        if (StringUtils.isEmpty(result.getName())) {// 姓名为空，取昵称
            result.setName(userInfo.getNickName());
        }

        result.setToken(JwtHelper.createToken(userInfo.getId(), result.getName()));
        return result;
    }

    @Override
    public boolean tryAuthentication(UserAuthDto authInfo) {
        return this.userInfoMapper.tryAuthentication(authInfo) == 1;
    }

    @Override
    public UserQueryVo selectById(Long id) {
        UserQueryVo user = this.userInfoMapper.selectById(id);
        if (user == null) {
            return null;
        }

        String statusString = user.getStatus().byteValue() == 0 ? "锁定" : "正常";
        UserQueryVo.OtherInfo otherInfo = new UserQueryVo.OtherInfo();

        otherInfo.setAuthStatusString(AuthStatusEnum.getStatusNameByStatus(user.getAuthStatus()));// 翻译认证状态
        otherInfo.setStatusString(statusString);

        user.setParam(otherInfo);
        return user;
    }

    /**
     * 校验验证码
     *
     * @param param 手机号、验证码……
     */
    private void checkLoginVerificationCode(VerificationCodeDto param) {
        String rightCode = this.redisTemplate.opsForValue()
                .get(UserRedisConstants.LOGIN_VERIFICATION_CODE + param.getPhone());
        if (rightCode == null || rightCode.length() == 0) {
            throw new BusinessException("验证码尚未发送或已过期", ResultCodeEnum.CODE_ERROR.getCode());
        } else if (!rightCode.equals(param.getCode())) {
            throw new BusinessException("验证码错误", ResultCodeEnum.CODE_ERROR.getCode());
        } else {
            this.redisTemplate.delete(UserRedisConstants.LOGIN_VERIFICATION_CODE + param.getPhone());
        }
    }

    @Override
    public UserInfo insertPhoneUser(String phone) {
        UserInfo userInfo = new UserInfo();
        userInfo.setNickName("用户" + phone.substring(7));// 用户+手机后四位
        userInfo.setPhone(phone);
        userInfo.setStatus(UserInfoConstants.STATUS_NOT_LOCKED);// 未锁定
        userInfo.setAuthStatus(AuthStatusEnum.NO_AUTH.getStatus());// 未认证
        userInfo.setIsDeleted(BaseEntityConstants.NOT_DELETED);// 未删除
        this.userInfoMapper.insert(userInfo);
        return userInfo;
    }

    @Override
    public Page<UserQueryVo> selectPage(Page<UserQueryVo> page, UserQueryDto conditions) {
        Page<UserQueryVo> pageResult = this.userInfoMapper.selectPage(page, conditions);

        // 字典翻译
        if (pageResult.getRecords().isEmpty()) {
            return pageResult;
        }

        for (UserQueryVo user : pageResult.getRecords()) {
            UserQueryVo.OtherInfo otherInfo = new UserQueryVo.OtherInfo();
            otherInfo.setAuthStatusString(AuthStatusEnum.getStatusNameByStatus(user.getAuthStatus()));// 翻译认证状态

            String statusString = user.getStatus().byteValue() == 0 ? "锁定" : "正常";
            otherInfo.setStatusString(statusString);
            user.setParam(otherInfo);
        }

        return pageResult;
    }

    @Override
    public boolean updateStatus(Long id, Byte status) {
        return this.userInfoMapper.updateStatus(id, status, new Date()) == 1;
    }

    @Override
    public boolean updateAuthStatus(Long id, Byte oldAuthStatus, Byte newAuthStatus) {
        return this.userInfoMapper.updateAuthStatus(id, oldAuthStatus, newAuthStatus, new Date()) == 1;
    }

}
